/*!
 *  @author  xiaody <xiaody09@163.com>
 *  @description  Config module for BDB.
 */

(function(){

	'use strict';

	var ConfigContent = {

		defaultSetting : {
			// The following three proporties will be set later.
			all : [	],
			enabled : [ ],
			disabled : [ ],
			readOnly : ['youStyle'],
			formatVersion : 2
		},

		displayGroup : {
			groupName : '隐藏',
			checkBoxes : {
				id : ['i_reply', 'HiRightTop', 'popRightTop', 'out_notice', 'in_dingUp'],
				text : ['I 贴吧主页新提醒', '右上角Hi', '右上角提醒', '贴吧公告', '一楼的顶按钮'],
				enable : [ false, false, false, false, false ],
				selector : [
					'#newTopPanel+div[style]',
					'#hiIcon, #hiMsg',
					'.tb_message_tip_new',
					'#thread_list_table>tbody>tr:not([tid])',
					'.p_ding_up'
				]
			}
		},

		defaultGroup : [
			{
				groupName : '功能',
				checkBoxes : {
					id : ['signSwitch', 'nightMode', 'lastPageLink', 'ipLookup', 'floorLink', 'editorPlus', 'decodePost'],
					text : ['签名档开关', '夜间模式开关', '尾页链接', 'ip党地理位置查询', '楼层链接', '发贴辅助', '解析贴中的密语/UUcode'],
					enable : [ true, false, true, false, false, false, true ]
				}
			}, {
				groupName : '样式',
				checkBoxes : {
					id : ['youStyle', 'youColor'],
					text : ['使用BDB样式', '使用BDB配色'],
					enable : [ true, true ]
				}
			}, {
				groupName : '风格',
				checkBoxes : {
					id : ['singleTab', 'JKscroll'],
					text : ['单标签浏览', 'G+风格楼层间滚动'],
					enable : [ false, false ]
				}
			}
		]
	}; // End of ${ConfigContent}.


	var Config = {

		init : function(){
			'use strict';

			// Do nothing if it's outside I-Tieba.
			if(pathhead !== 'i')
				return;

			// Insert a config side-button only if it's user's own I-Tieba.
			if($('#aside_menu')){
				var aside_config_li = document.createElement('li').attr('class', 'aside_config_li');
				var	aside_config = document.createElement('a').attr({
						id : 'aside_config',
						st_type : 'aside_config',
						href : ''
				});
				aside_config.innerText = 'BDB设置';
				aside_config_li.appendChild(aside_config);
				$('#aside_menu').firstElementChild.appendChild(aside_config_li);

				// If the page comes from a refresh or redirect,
				// enter the config page directly.
				if(location.hash === "#!BDB_config")
					Config.enter();
				else
					aside_config.addEventListener('click', Config.enter, true);

				// Get jQuery.dialog for later use.
				var jQuery = document.createElement('A').attr('onclick','javascript:return window.jQuery').onclick();
				window.Dialog = (jQuery && jQuery.dialog) || window;
			}
		},

		enter : function(){
			// Prevent the click event.
			window.event && window.event.preventDefault();

			// Set aside menu appearance.
			var lis = $$('#aside_menu li');
			for(var i = 0, l = lis.length, li; i < l; i++) {
				li = lis[i];
				if(li.classList.contains('sel')){
					li.classList.remove('sel');
					var id = li.className.replace(/_li$/ ,'');

					// Due to a Tieba's bug, the ${id} may be like 'aside_noticeaside_notice',
					// we need to fix it.
					if(/aside_\w+aside_/.test(id))
						id = id.substr(0, id.length / 2);
					else
						log('A TiebaBug has been fixed, take a look.');

					var userNum = location.pathname.match(/\d+/);
					li.html('<a id='+id+' st_type='+id+' href="/i/'+userNum+asidePathTable[id]+'">'+lis[i].innerText+'</a>');
					break;
				}
			}
			var aside_config_li = $('.aside_config_li');
			aside_config_li.classList.add('sel');
			aside_config_li.$text('BDB设置');

			// Push a url in history.
			history.pushState({}, 'BaiDu Beautifier设置', '/#!BDB_config');
			document.title = 'BaiDu Beautifier设置';

			Config.contentFill();

		},

		contentFill : function(){
			'use strict';

			var content = $('#content'), frag = document.createDocumentFragment();

			frag.appendChild(createConfigGroup(displayGroup));
			for(var i = 0, l = defaultGroup.length; i < l; i++){
				frag.appendChild(createConfigGroup(defaultGroup[i]));
			}

			// Insert save&cancel buttons.
			frag.appendChild(createSaveButtonsSection());
			frag.appendChild(createSupportSection());

			/*! Copyright (c) 2012 The Chromium Authors. All rights reserved.
			 * Use of this source code is governed by a BSD-style license that can be
			 * found in the LICENSE file. */
			var scopedStyle = document.createElement('style').attr('scoped', '');
			scopedStyle.$text("input[type='checkbox']{-webkit-box-shadow:inset 0 1px 2px white,0 1px 2px rgba(0,0,0,.2);-webkit-appearance:none;-webkit-margin-start:0;-webkit-margin-end:3px;background:-webkit-linear-gradient(#fafafa,#dcdcdc);border:1px solid #a0a0a0;display:inline-block;margin-bottom:0;margin-top:0;position:relative;border-radius:3px;height:16px;width:16px}input[type='checkbox']:disabled{opacity:.75}input[type='checkbox']:not(:disabled):not(:active):hover{background:-webkit-linear-gradient(#fff,#e6e6e6);text-shadow:0 1px 0 rgba(255,255,255,1)}input[type='checkbox']:not(:disabled):active{-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.2);background:-webkit-linear-gradient(#f0f0f0,#bebebe);border:1px solid #808080;text-shadow:0 1px 0 rgba(255,255,255,.25)}input[type='checkbox']:checked::before{-webkit-user-select:none;color:#808080;content:url();font-size:13px;height:16px;left:2px;position:absolute}");

			content.html('<h2 id=bdb_config_title>BaiDu Beautifier设置</h2>');
			content.pushChild(scopedStyle).appendChild(frag);
			Config.restore();

			$('#footer').attr('hidden', '');

			// Ask for persistent file storage permission.
			webkitStorageInfo.requestQuota( webkitStorageInfo.PERSISTENT, 5*1024*1024 );

		},

		store : function(){
			'use strict';

			var enabled = [], disabled = [], name;

			for(var i = 0, l = defaultSetting.all.length; i < l; i++){
				name = defaultSetting.all[i];
				if(defaultSetting.readOnly.contains(name)) {
					if(defaultSetting.enabled.contains(name))
						enabled.push(name);
					else
						disabled.push(name);
				}
				else if($('#' + name).checked)
					enabled.push(name);
				else
					disabled.push(name);
			}

			var settingStr = JSON.stringify( {
					'formatVersion' : 2,
					'enabled' : enabled,
					'disabled': disabled,
					'time' : + new Date()
			} );
			settingStr = btoa(settingStr);
			localStorage['__BDB_configSetting__'] = settingStr;

			File.write('BDB_configSetting.txt', settingStr);

			if(localStorage['__BDB_configSetting__'] === settingStr) {

				// Force the getConfigSetting function to recache the setting.
				delete getConfigSetting.cachedSetting;

				Dialog.alert('<center style="font-size:14px">保存成功<center>', {title:'BDB'});
			}

		},

		restore : function(){
			'use strict';

			var configSetting = getConfigSetting(), i;

			var name, toCheck;
			for(i = defaultSetting.all.length; i--;) {

				name = defaultSetting.all[i];

				if(configSetting.enabled.contains(name)) {
					toCheck = true;
				} else if(typeof configSetting.disabled !== 'undefined' && configSetting.disabled.contains(name)) {
					toCheck = false;
				} else {
					toCheck = defaultSetting.enabled.contains(name);
				}

				$('#' + name).checked = toCheck;
			}

		},

		get : function(configName){
			'use strict';
			var configSetting = getConfigSetting();
			if(defaultSetting.readOnly.contains(configName)) {
				configSetting = defaultSetting;
			}

			if(configSetting.enabled.contains(configName))
				return true;
			else if(typeof configSetting.disabled !== 'undefined' && configSetting.disabled.contains(configName))
				return false;
			else
				return defaultSetting.enabled.contains(configName);
		}
	}; // End of ${Config}.



	var defaultGroup = ConfigContent.defaultGroup,
	displayGroup = ConfigContent.displayGroup,
	defaultSetting = ConfigContent.defaultSetting;


	// Generate ConfigContent.defaultSetting;
	defaultSetting.all = (function(){
		var ret = [];
		var groups = defaultGroup.concat([displayGroup]);
		for(var i = 0, l = groups.length; i < l; i++) {
			ret = ret.concat(groups[i].checkBoxes.id);
		}
		return ret;
	})();
	(function(){
		var i, j, checkBoxes;
		var groups = defaultGroup.concat([displayGroup]);
		for(i = groups.length; i--;) {
			checkBoxes = groups[i].checkBoxes;
			for(j = checkBoxes.id.length; j--;) {
				if(checkBoxes.enable[j] == true)
					defaultSetting.enabled.push(checkBoxes.id[j]);
				else
					defaultSetting.disabled.push(checkBoxes.id[j]);
			}
		}
	})();


	// Side menu href table.
	var asidePathTable = {
		aside_home : '',
		aside_mytie : '/my_tie',
		aside_forum : '/forum',
		aside_notice : '/replyme'

	};

	var basedProjects = [
		{ name: 'Chromium project', url : 'https://code.google.com/intl/en-US/chromium/' },
		{ name: 'Adblock ChinaList', url : 'https://code.google.com/p/adblock-chinalist/' },
		{ name: '百度密语', url : 'https://code.google.com/p/baidumiyu/' },
		{ name: 'WebToolKit', url : 'http://www.webtoolkit.info/' }
	];

	// Get the config setting object.
	function getConfigSetting(){

		if(typeof getConfigSetting.cachedSetting !== 'undefined') {
			return getConfigSetting.cachedSetting;
		}

		var ret;
		if(typeof localStorage['__BDB_configSetting__'] !== 'undefined') {
			ret = atob(localStorage['__BDB_configSetting__']);
			ret = JSON.parse(ret);
		} else {
			setTimeout(function(){
				if(typeof localStorage['__BDB_configSetting__'] === 'undefined')
					localStorage['__BDB_configSetting__'] = btoa(JSON.stringify(defaultSetting));
			}, 3000);
			ret = defaultSetting;
		}

		// Cache the setting, cuz decoding base64 string is slow.
		getConfigSetting.cachedSetting = ret;

		return ret;
	}

	function createSupportSection(){
		var section = document.createElement('footer').attr('class', 'bdb_support_section bdb_config_section');
		var h3 = document.createElement('h3').$text('About'),
			div = document.createElement('div');
		var p = document.createElement('p').html(
				'BaiDu Beautifier by <a href=/i/18700119 rel=author>@悠悠奈何</a>; All Rights Reserved.<br>' +
				'BaiDu Beautifier is made possible by the following open source projects:<br>'
		),	ul = document.createElement('ul').attr('id', 'based_projects');

		var i = 0, l = basedProjects.length, ulHTML = '', url, name;
		for(; i<l; i++) {
			name = basedProjects[i].name;
			url = basedProjects[i].url;
			ulHTML += '<a href=' + url + ' target=_blank><li>' + name + '</li></a>';
		}
		ul.html(ulHTML);

		div.pushChild(p).pushChild(ul);

		var support = document.createElement('p').html(
				'支持：加入<a href=/f?kw=%D3%C6%D3%C6%C4%CE%BA%CE> 悠悠奈何 </a>吧以鼓励作者继续维护此扩展并进行下一步开发；<br>'  +
				'有问题/建议？欢迎来此贴反馈：<a href=/p/1412237656 target=_blank>http://tieba.baidu.com/p/1412237656</a>'
		).attr('style',  'padding-left:130px');
		section.pushChild(h3).pushChild(div).appendChild(support);
		return section;
	}

	function createSaveButtonsSection(){
		var saveButtonSection = document.createElement('section').attr('class', 'bdb_save_section');
		var _save = document.createElement('input').attr({
			id : "config_save",
			type : "image",
			src : "http://static.tieba.baidu.com/tb/static-itieba3/img/user_save.png"
		}), _cancel = document.createElement('input').attr({
			id : "config_cancel",
			type : "image",
			src : "http://static.tieba.baidu.com/tb/static-itieba3/img/cancel_user.png"
		});
		_save.addEventListener('click', Config.store, true);
		_cancel.addEventListener('click', Config.restore, true);
		return saveButtonSection.pushChild(_save).pushChild(_cancel);
	}

	function createConfigGroup(gConfig){
		'use strict';
		var section = document.createElement('section').attr('class', 'bdb_config_section');
		var h3 = document.createElement('h3').$text(gConfig.groupName),
			div = document.createElement('div');

		var i = 0, l = gConfig.checkBoxes.id.length, divHTML = '', id, text;
		for(; i<l; i++){
			id = gConfig.checkBoxes.id[i];
			text = gConfig.checkBoxes.text[i];
			divHTML += '<div class=checkbox><label><input type=checkbox id=' + id +
					(defaultSetting.readOnly.indexOf(id) === -1 ? '' : ' disabled') +
					'><span>'+text+'</span></label></div>';
		}
		div.html(divHTML);
		section.pushChild(h3).pushChild(div);
		return section;
	}


	// File system APIs module.
	var File = {

		write : function(name, data, callback) {
			'use strict';

			callback = callback || {};
			var errorHandler = callback.error || function(e){console.error(e)};
			var onInitFs = function(fs){

				fs.root.getFile(name, {create: true}, function(fileEntry) {

					fileEntry.createWriter(function(fileWriter) {

						var bb = new BlobBuilder();
						bb.append(data);
						fileWriter.write(bb.getBlob('text/plain'));

					}, errorHandler);

				}, errorHandler);
			}

			requestFileSystem(window.PERSISTENT, 1024*1024, onInitFs, errorHandler);
		},

		read : function(name, callback) {
			'use strict';

			callback = callback || {};
			var errorHandler = callback.error || function(e){console.error(e)};
			var successHandler = callback.success || function(){console.log('File read successed.')};
			var onInitFs = function(fs){

				fs.root.getFile(name, {}, function(fileEntry) {

					fileEntry.file(function(file) {
						var reader = new FileReader();

						reader.onloadend = function(e) {
							successHandler(reader.result);
						};

						reader.readAsText(file);
					}, errorHandler);

				}, errorHandler);
			}

			requestFileSystem(window.PERSISTENT, 1024*1024, onInitFs, errorHandler);
		}

	}; // End of ${File}.


	// Expose to global.
	window.File = File;
	window.Config = Config;
	window.ConfigContent = ConfigContent;


})();
